<?php

/**
 *
 * 文件上传类
 *
 *
 * @version 1.0
 * @author Human
 */
class uploadfile_c
{
    /**
     * 错误信息数组
     */
    public $error_message = array();
    /**
     * 文件大小限制 单位为M
     */
    public $size_limit = 2;
    /**
     * 文件类型限制
     */
    public $type_limit = null;
    /**
     * 上传文件控件名
     */
    public $upload_name = '';
    /**
     * 文件保存路径 最后需要'/'
     */
    public $file_save_path = '';
    /**
     *  文件名保存名 遇到同名覆盖 如果同时上传多文件 在名称后面自动排序[_x],
     *  默认*auto使用 [user_id]_[datetime]_[随机数].后缀名
     * @var string
     */
    public $file_save_name = '*auto';
    /**
     * 上传文件成功后的文件信息数组 上传单个文件则长度为1 多个文件为数组长度
     */
    public $file_message = array();
    /**
     * 生成缩略图的高度 默认128
     * @var int
     */
    public $height_mini = 128;
    /**
     * 生成缩略图的宽度 默认128
     * @var int
     */
    public $width_mini = 128;
    /**
     * 自动压缩原图并覆盖 默认true
     * 如果当$auto_mini=1&&$auto_dele=1自动生成缩略图与删除原图，
     * 将不压缩原图 而是直接用原图生成缩略图后 删除原图
     * @var bool
     */
    public $auto_press_source = TRUE;
    /**
     * 原图压缩后的高度 默认768
     * @var int
     */
    public $height_press_source = 768;
    /**
     * 原图缩略图的宽度 默认1024
     * @var int
     */
    public $width_press_source = 1024;

    /**
     * 水印字体的含路径文件名
     * @var string
     */
    public $font_path = '';

    /**
     * 是否添加水印
     * @var bool
     */
    public $add_text = false;

    /**
     * 上传文件
     * @param bool 是否自动生成缩略图
     * @param bool 生成缩略图后是否自动删除原图
     * @return bool 上传成功
     */
    public function upload_file($auto_mini, $auto_dele = false)
    {
        if (empty($_FILES[$this->upload_name]['name'])) {
            $this->error_message[0] = "错误:文件有误，未检测到上传文件";
            return false;
        }
        $file_ary = array();
        //如果使用多文件上传 
        if (is_array($_FILES[$this->upload_name]['name'])) {
            $file_ary = $this->reArrayFiles($_FILES[$this->upload_name]);
        } else {
            $file_ary[0] = $_FILES[$this->upload_name];
        }
        for ($i = 0; $i < count($file_ary); $i++) {
            if ($file_ary[$i]["error"] > 0) {
                if ($file_ary[$i]["error"] == 4) {
                    $this->error_message[$i] = "错误:文件没有上传";
                    break;
                } else {
                    $this->error_message[$i] = "错误:文件上传错误代码:{$file_ary[$i]['error']}";
                    return $this->upload_false();
                }
            }
            if ($file_ary[$i]['name'] != '') {
                $LastName = strtolower(substr(strrchr($file_ary[$i]['name'], '.'), 1));
                if (empty($LastName)) {
                    $this->error_message[$i] = "错误:文件有误，无扩展名";
                    return $this->upload_false();
                }
            }
            if ($this->type_limit != null) {
                if (is_array($this->type_limit)) {
                    if (!in_array($LastName, $this->type_limit)) {
                        $this->error_message[$i] = "错误:文件格式限制：" . implode(',', $this->type_limit);
                        return $this->upload_false();
                    }
                } else {
                    if ($LastName != $this->type_limit) {
                        $this->error_message[$i] = "错误:文件格式限制：" . $this->type_limit;
                        return $this->upload_false();
                    }
                }
            }
            if ($file_ary[$i]["size"] / 1024 / 1024 > $this->size_limit) {
                $this->error_message[$i] = "错误:文件大小限制" . $this->size_limit . "MB";
                return $this->upload_false();
            }
            if (!$this->check_freeSpace($file_ary[$i]["size"])) {
                $this->error_message[$i] = "错误:服务器空间大小不足";
                return $this->upload_false();
            }
            if (!file_exists($this->file_save_path)) {
                $filepathok = mkdir($this->file_save_path);
            } else {
                $filepathok = true;
            }
            if ($filepathok) {
                $this->file_message[$i]['name_ex'] = $LastName; // 扩展名
                if ($this->file_save_name != "*auto") //固定式存储名称 可覆盖
                {
                    if (count($file_ary) == 1) {
                        $this->file_message[$i]['name'] = $this->file_save_name . '.' . $LastName;
                    } else {
                        $this->file_message[$i]['name'] = $this->file_save_name . "_{$i}." . $LastName;
                    }
                    $this->file_message[$i]['name_mini'] = $this->file_save_name . ".mini" . '.' . $LastName;
                    $this->file_message[$i]['fullname'] = $this->file_save_path . $this->file_message[$i]['name'];
                    $this->file_message[$i]['fullname_mini'] = $this->file_save_path . $this->file_message[$i]['name_mini'];
                } else //时间+随机数字存储名
                {
                    $this->file_message[$i]['name'] = $_SESSION['user_id'] . '_' . date('YmdHis') . '_' . $i . rand();
                    $this->file_message[$i]['name_mini'] = $this->file_message[$i]['name'] . ".mini" . '.' . $LastName;
                    $this->file_message[$i]['name'] .= '.' . $LastName;
                    $this->file_message[$i]['fullname'] = $this->file_save_path . $this->file_message[$i]['name'];
                    $this->file_message[$i]['fullname_mini'] = $this->file_save_path . $this->file_message[$i]['name_mini'];
                }
                if (move_uploaded_file($file_ary[$i]["tmp_name"], $this->file_message[$i]['fullname'])) {
                    $this->file_message[$i]['old_name'] = $file_ary[$i]['name'];
                    $this->file_message[$i]['size'] = (string)$file_ary[$i]["size"];
                    $srcinfo = getimagesize($this->file_message[$i]['fullname']);
                    $src_w = $srcinfo[0];
                    $src_h = $srcinfo[1];
                    if ($auto_mini) {
                        //如果原图的宽高都小于缩略图的宽高 直接copy
                        if ($src_w < $this->width_mini && $src_h < $this->height_mini) {
                            if (copy($this->file_message[$i]['fullname'], $this->file_message[$i]['fullname_mini'])) {
                                if ($auto_dele) {//删除原图
                                    @unlink($this->file_message[$i]['fullname']);
                                }
                            } else {
                                $this->error_message[$i] = "错误:拷贝缩略图失败";
                                return $this->upload_false();
                            }
                        } else {
                            if ($this->img2thumb($this->file_message[$i]['fullname'],
                                $this->file_message[$i]['fullname_mini'],
                                $this->width_mini, $this->height_mini, 1)
                            ) {
                                if ($auto_dele) {//删除原图
                                    @unlink($this->file_message[$i]['fullname']);
                                }
                            } else {
                                $this->error_message[$i] = "错误:生成缩略图失败";
                                return $this->upload_false();
                            }
                        }
                    }
                    if (($auto_mini !== TRUE || $auto_dele !== TRUE) &&
                        $this->auto_press_source === TRUE
                    ) {
                        //对原图压缩
                        //如果原图的宽高都小于压缩指定的宽高 将不处理
                        if ($src_w < $this->width_press_source && $src_h < $this->height_press_source) {
                        } else {
                            if ($this->img2thumb($this->file_message[$i]['fullname'],
                                $this->file_message[$i]['fullname'],
                                $this->width_press_source,
                                $this->height_press_source,
                                1)
                            ) {
                            } else {
                                $this->error_message[$i] = "错误:压缩原图失败";
                                return $this->upload_false();
                            }
                        }
                    }
                    if ($this->add_text) //添加水印
                    {
                        if ($auto_mini) {
                            if ($this->imgWithText($this->file_message[$i]['fullname_mini'])) {
                                $this->error_message[$i] = "错误:缩略图添加水印失败";
                                return $this->upload_false();
                            }
                        }
                        if ($this->imgWithText($this->file_message[$i]['fullname'])) {
                            $this->error_message[$i] = "错误:添加水印失败";
                            return $this->upload_false();
                        }
                    }
                } else {
                    $this->error_message[$i] = "错误:文件移动到指定路径失败" . $this->file_save_path;
                    return $this->upload_false();
                }
            } else {
                $this->error_message[$i] = "错误:访问服务器文件路径失败 " . $this->file_save_path;
                return $this->upload_false();
            }
        }
        return true;
    }

    function reArrayFiles(&$file_post)
    {
        $file_ary = array();
        $file_count = count($file_post['name']);
        $file_keys = array_keys($file_post);
        for ($i = 0; $i < $file_count; $i++) {
            foreach ($file_keys as $key) {
                $file_ary[$i][$key] = $file_post[$key][$i];
            }
        }
        return $file_ary;
    }

    function upload_false()
    {
        //删除掉临时文件
        if (isset($_FILES[$this->upload_name]))
            if (is_array($_FILES[$this->upload_name]['name'])) {
                foreach ($_FILES['img_upload']['tmp_name'] as $filename) {
                    @unlink($filename);
                }
            } else {
                @unlink($_FILES['img_upload']['tmp_name']);
            }
        foreach ($this->file_message as $file_msg) {
            @unlink($file_msg['fullname']);
            @unlink($filename['fullname_mini']);
        }
        return false;
    }

    /**
     * 检查剩余空间是否足够
     */
    function check_freeSpace($filesize)
    {
        return (disk_free_space(getcwd()) > $filesize * 2);
    }

    /**
     * 生成缩略图
     * @param string     源图绝对完整地址{带文件名及后缀名}
     * @param string     目标图绝对完整地址{带文件名及后缀名}
     * @param int        缩略图宽{0:此时目标高度不能为0，目标宽度为源图宽*(目标高度/源图高)}
     * @param int        缩略图高{0:此时目标宽度不能为0，目标高度为源图高*(目标宽度/源图宽)}
     * @param int        是否裁切{宽,高必须非0}
     * @param int  缩放{0:不缩放, 0<this<1:缩放到相应比例(此时宽高限制和裁切均失效)}
     * @return boolean
     */
    function img2thumb($src_img, $dst_img, $width = 75, $height = 75, $cut = 0, $proportion = 0)
    {
        if (!is_file($src_img)) {
            return false;
        }
        $ot = $this->fileext($dst_img);
        $otfunc = 'image' . ($ot == 'jpg' ? 'jpeg' : $ot);
        $srcinfo = getimagesize($src_img);
        $src_w = $srcinfo[0];
        $src_h = $srcinfo[1];
        $type = strtolower(substr(image_type_to_extension($srcinfo[2]), 1));
        $createfun = 'imagecreatefrom' . ($type == 'jpg' ? 'jpeg' : $type);

        $dst_h = $height;
        $dst_w = $width;
        $x = $y = 0;

        /**
         * 缩略图不超过源图尺寸（前提是宽或高只有一个）
         */
        if (($width > $src_w && $height > $src_h) || ($height > $src_h && $width == 0) || ($width > $src_w && $height == 0)) {
            $proportion = 1;
        }
        if ($width > $src_w) {
            $dst_w = $width = $src_w;
        }
        if ($height > $src_h) {
            $dst_h = $height = $src_h;
        }

        if (!$width && !$height && !$proportion) {
            return false;
        }
        if (!$proportion) {
            if ($cut == 0) {
                if ($dst_w && $dst_h) {
                    if ($dst_w / $src_w > $dst_h / $src_h) {
                        $dst_w = $src_w * ($dst_h / $src_h);
                        $x = 0 - ($dst_w - $width) / 2;
                    } else {
                        $dst_h = $src_h * ($dst_w / $src_w);
                        $y = 0 - ($dst_h - $height) / 2;
                    }
                } else if ($dst_w xor $dst_h) {
                    if ($dst_w && !$dst_h)  //有宽无高
                    {
                        $propor = $dst_w / $src_w;
                        $height = $dst_h = $src_h * $propor;
                    } else if (!$dst_w && $dst_h)  //有高无宽
                    {
                        $propor = $dst_h / $src_h;
                        $width = $dst_w = $src_w * $propor;
                    }
                }
            } else {
                if (!$dst_h)  //裁剪时无高
                {
                    $height = $dst_h = $dst_w;
                }
                if (!$dst_w)  //裁剪时无宽
                {
                    $width = $dst_w = $dst_h;
                }
                $propor = min(max($dst_w / $src_w, $dst_h / $src_h), 1);
                $dst_w = (int)round($src_w * $propor);
                $dst_h = (int)round($src_h * $propor);
                $x = ($width - $dst_w) / 2;
                $y = ($height - $dst_h) / 2;
            }
        } else {
            $proportion = min($proportion, 1);
            $height = $dst_h = $src_h * $proportion;
            $width = $dst_w = $src_w * $proportion;
        }

        $src = $createfun($src_img);
        $dst = imagecreatetruecolor($width ? $width : $dst_w, $height ? $height : $dst_h);
        $white = imagecolorallocate($dst, 255, 255, 255);
        imagefill($dst, 0, 0, $white);

        if (function_exists('imagecopyresampled')) {
            imagecopyresampled($dst, $src, $x, $y, 0, 0, $dst_w, $dst_h, $src_w, $src_h);
        } else {
            imagecopyresized($dst, $src, $x, $y, 0, 0, $dst_w, $dst_h, $src_w, $src_h);
        }
        $otfunc($dst, $dst_img);
        imagedestroy($dst);
        imagedestroy($src);
        return true;
    }

    function fileext($file)
    {
        return pathinfo($file, PATHINFO_EXTENSION);
    }

    /**
     * 添加水印
     * @param  string $srcPath 需要添加水印的源图片完整路径
     * @oaram  string $desPath 添加水印后保存图片的完整路径
     * @return boolean
     */
    public function imgWithText($srcPath, $desPath)
    {
        if (!is_file($srcPath)) {
            return false;
        }

        //源图 当前原图都是固定为1024*768 jpeg格式
        $imSrc = imagecreatefromjpeg($srcPath);
        //文字字体
        $font = $this->font_path;
        $fontSize1 = 31;    //水印标题字体大小
        $fontSize2 = 19;    //水印内容字体大小
        //定义水印的字体颜色与背景颜色
        $colorBack = imagecolorallocatealpha($imSrc, 255, 255, 255, 95);
        $colorText = imagecolorallocatealpha($imSrc, 255, 255, 255, 30);

        //水印图底色填充
        imagefilledrectangle($imSrc, 670, 70, 1023, 240, $colorBack);

        //水印文字
        $t1 = "Sneaker Custom"; //标题为粗体，画两遍，坐标偏移1位，制造出粗体效果
        imagettftext($imSrc, $fontSize1, 0, 690, 130, $colorText, $font, $t1);
        imagettftext($imSrc, $fontSize1, 0, 691, 131, $colorText, $font, $t1);
        $t2 = "www.Sneaker-Custom.com";
        imagettftext($imSrc, $fontSize2, 0, 692, 171, $colorText, $font, $t2);
        $t3 = "ID:{$_SESSION['user_name']}";
        $fontBox = imagettfbbox($fontSize2, 0, $font, $t3);//文字的大小
        $x = ceil((355 - $fontBox[2]) / 2) + 670;//计算文字的水平位置
        imagettftext($imSrc, $fontSize2, 0, $x, 215, $colorText, $font, $t3);
        //生成图片
        $result = imagejpeg($imSrc, $desPath);
        imagedestroy($imSrc);
        return $result;
    }

}